home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
DDJ0192.ARJ
/
DISKIO.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-04
|
6KB
|
257 lines
/****************************************************************
* *
* DISKIO.C Whole disk I/O routines for CB386 *
* See makefile for compile directives *
* Al Williams -- August 1991 *
* *
****************************************************************/
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <dos.h>
#include "cb386.h"
#include "display.h"
/* The BIOS read/write routines use a DOS buffer since
codebuilder does not transparently move data for these
BIOS interrupts */
/* read count number of sectors via the BIOS
returns 0 for success */
sector_read(int head,int track, int sector, int drive,
unsigned char *buf,unsigned count)
{
int try=NRTRIES;
union REGS r;
/* if no dos buffer then allocate one large enough for
one track */
if (!dosbuf)
{
r.h.ah=0x48;
r.x.bx=bpb.bytespersec*bpb.secpertrack;
int86(0x21,&r,&r);
if (r.x.cflag)
{
advise("Not enough DOS memory");
return 1;
}
dosbuf=(char *)r.x.ax;
}
/* do operation up to try times */
while (try--)
{
r.h.ah=2;
r.h.al=count;
r.h.dh=head;
r.h.dl=drive;
r.h.ch=track;
r.h.cl=sector;
r.x.bx=(unsigned)dosbuf;
int86(0x13,&r,&r);
/* if error... */
if (r.x.cflag)
{
/* if not last try */
if (try)
{
/* reset drive and try again */
r.x.ax=0;
r.h.dl=drive;
int86(0x13,&r,&r);
}
/* continue on all errors */
continue;
}
/* no error -- move data to user's buffer and return success */
memcpy(buf,dosbuf,bpb.bytespersec*count);
return 0;
}
/* if try runs out -- return 1 */
return 1;
}
/* read entire disk */
read_disk(int drive)
{
unsigned i,trk=0,head=0;
unsigned char *diskp;
/* erase existing image, if any */
if (diskbuf) free(diskbuf);
/* set up buffer info */
strcpy(bufinfo.title,"<NONE>");
bufinfo.source[0]=toupper(drive);
driveno=bufinfo.source[0]-'A';
bufinfo.source[1]=':';
bufinfo.source[2]='\0';
dosbuf_free();
/* turn on wait indicator on screen */
wait_on();
/* read BPB from specified drive */
bpb.bytespersec=512; /* default */
bpb.secpertrack=1;
if (sector_read(head,0,1,driveno,(unsigned char *)&bpb,1))
{
advise("Can't read bpb");
return 0;
}
if (dosbuf) dosbuf_free();
head=0;
/* determine size of disk */
bufinfo.size=disksize=
(sectorct=bpb.nrsectors?bpb.nrsectors:
bpb.hugesectors)
*bpb.bytespersec;
/* allocate space */
diskbuf=(unsigned char *)malloc(disksize);
if (!diskbuf)
{
advise("Not enough free memory");
return 0;
}
/* read entire disk */
diskp=diskbuf;
goxy(0,12);
histogram(-1,60);
curshide();
for (i=0;i<sectorct;i+=bpb.secpertrack)
{
histogram(i,sectorct);
if (sector_read(head,trk,1,driveno,diskp,bpb.secpertrack))
{
char errbuf[80];
sprintf(errbuf,"\aWarning: bad sector at %u:%u\n",head,trk);
if (advise(errbuf)==-1)
{
cleanup(); /* kill incomplete buffer */
return 0;
}
}
diskp+=bpb.bytespersec*bpb.secpertrack;
if (++head>=bpb.nrheads)
{
head=0;
trk++;
}
}
bufinfo.dirty=1;
histogram(i,i);
bufinfo.csum=checksum();
wait_off();
return 1;
}
/* free dos buffer */
dosbuf_free()
{
union REGS r;
if (!dosbuf) return;
r.h.ah=0x49;
r.x.dx=(unsigned int)dosbuf;
int86(0x21,&r,&r);
if (r.x.cflag)
advise("Memory allocation error");
dosbuf=NULL;
}
/* write count sectors via BIOS */
sector_write(int head,int track, int sector, int drive,
unsigned char *buf,unsigned count)
{
int try=NRTRIES;
union REGS r;
/* If no dos buffer, allocate one */
if (!dosbuf)
{
r.h.ah=0x48;
r.x.bx=bpb.bytespersec*bpb.secpertrack;
int86(0x21,&r,&r);
if (r.x.cflag)
{
advise("Not enough DOS memory");
return;
}
dosbuf=(char *)r.x.ax;
}
/* copy data to dosbuffer */
memcpy(dosbuf,buf,bpb.bytespersec*count);
/* retry up to try times */
while (try--)
{
r.h.ah=3;
r.h.al=count;
r.h.dh=head;
r.h.dl=drive;
r.h.ch=track;
r.h.cl=sector;
r.x.bx=(unsigned)dosbuf;
int86(0x13,&r,&r);
/* if error.... */
if (r.x.cflag)
{
/* if not last try... */
if (try)
{
/* reset drive and try again */
r.x.ax=0;
r.h.dl=drive;
int86(0x13,&r,&r);
}
/* continue for all errors */
continue;
}
/* return success */
return 0;
}
/* fail */
return 1;
}
/* write entire disk */
write_disk(int drive)
{
int fmt=0;
unsigned i,trk=0,head=0;
unsigned char *diskp;
drive=toupper(drive)-'A';
/* turn on wait indicator */
wait_on();
retry:
goxy(0,12);
histogram(-1,60);
curshide();
head=0;
diskp=diskbuf;
/* write entire disk a track at a time */
for (i=0;i<sectorct;i+=bpb.secpertrack)
{
histogram(i,sectorct);
if (sector_write(head,trk,1,drive,diskp,bpb.secpertrack))
{
/* if error and format flag is on then error */
if (fmt)
{
advise("Write error");
return 0;
}
/* format disk and set format flag */
format(drive);
fmt=1;
/* retry (next error is fatal) */
goto retry;
}
diskp+=bpb.bytespersec*bpb.secpertrack;
if (++head>=bpb.nrheads)
{
head=0;
trk++;
}
}
histogram(i,i);
bufinfo.dirty=0;
wait_off();
return 1;
}